/**
 * DSM - Distributed Search Manager
 * Developed by Milspec Research International Pty Ltd
 * $Author: gsingh $
 * $Revision: 1.8 $
 * $Date: 2006/06/07 07:48:23 $
 * (c)Copyright 2004
 * education.au limited
 * DEST
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * Neither the names education.au limited, DEST nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 * To the extent permitted by law, the copyright owners of this software and
 * its contributors:
 * (i) exclude all warranties in relation to the software; and
 * (ii) exclude liability for all losses, costs, expenses and damages arising
 * in any way from the use of the software whether arising from or in
 * relation to breach of contract, negligence or any other tort, in equity
 * or otherwise. If the software is in breach of a warranty which is
 * implied by law, the copyright owners and contributors liability is
 * limited to the replacement of the software.
 *
 * @author	gsingh
 */

package au.edu.educationau.opensource.dsm.adapters;

import java.io.Reader;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Enumeration;

import au.edu.educationau.opensource.dsm.DeusExMachina;
import au.edu.educationau.opensource.dsm.adapters.contenthandler.SRWContentHandler;
import au.edu.educationau.opensource.dsm.cache.DiskCacheEntry;
import au.edu.educationau.opensource.dsm.obj.SearchCriteria;
import au.edu.educationau.opensource.dsm.util.Flog;
import au.edu.educationau.opensource.dsm.worker.ResultSetUnifier;

/**
 * SRU Adapter
 */

public class SRUSearchAdapterImpl extends SearchAdapter {
	private int startValue = 1;

	/** Parent constructor */
	public SRUSearchAdapterImpl() {
		super();
	}

	/**
	 * See the SearchAdapter abstract method doPrime
	 * 
	 * @exception Throwable
	 */
	public void doPrime() throws Throwable {
		SearchCriteria criteria = super.getSearchCriteria();
		addToURLBuffer("operation=searchRetrieve");
		addToURLBuffer("&query=");
		if (criteria.getCQLQuery() != null && criteria.getCQLQuery().length() > 0) {
			String cqlQuery = criteria.getCQLQuery();
			if (cqlQuery.toLowerCase().indexOf("cql.serverchoice") >= 0) {
				// this CQL is too complex for our NZEnc server
				// Simplify it
				cqlQuery = DeusExMachina._SearchManagerService().buildCQLFromQuery(criteria.getQueryArray(), criteria.getKeywordConstraint());
				Flog.info(toString(), "SRU Query is: " + cqlQuery);
			}
			addToURLBuffer(cqlQuery);
		} else {
			addToURLBuffer(URLEncoder.encode(criteria.getQuery(), "UTF-8"));
		}
		addToURLBuffer("&startRecord=");
		addToURLBuffer(startValue);
		addToURLBuffer("&maximumRecords=");
		addToURLBuffer(super.getProperties().getBatchSize());

		if (criteria.hasCustomParams()) {
			String param = "";
			String adapterName = super.getProperties().getAdapterCode() + ".";
			for (Enumeration params = criteria.getCustomParams(); params.hasMoreElements();) {
				param = (String) params.nextElement();
				if (param.startsWith(adapterName) && param.length() > adapterName.length()) {
					addToURLBuffer("&");
					addToURLBuffer(param.substring(adapterName.length()));
					addToURLBuffer("=");
					addToURLBuffer(criteria.getCustomParamValue(param));
				}
			}
		}

		if (getURLBuffer().indexOf("version=") < 0 && null != super.getProperties().getExtraProperty("version")) {
			addToURLBuffer("&version=");
			addToURLBuffer(super.getProperties().getExtraProperty("version"));
		}

		if (getURLBuffer().indexOf("x-user=") < 0 && null != super.getProperties().getExtraProperty("x-user")) {
			addToURLBuffer("&x-user=");
			addToURLBuffer(super.getProperties().getExtraProperty("x-user"));
		}

		if (getURLBuffer().indexOf("stylesheet=") < 0 && null != super.getProperties().getExtraProperty("stylesheet")) {
			addToURLBuffer("&stylesheet=");
			addToURLBuffer(super.getProperties().getExtraProperty("stylesheet"));
		}

		if (getURLBuffer().indexOf("recordSchema=") < 0 && null != super.getProperties().getExtraProperty("recordSchema")) {
			addToURLBuffer("&recordSchema=");
			addToURLBuffer(super.getProperties().getExtraProperty("recordSchema"));
		}

		if (getURLBuffer().indexOf("recordPacking=") < 0 && null != super.getProperties().getExtraProperty("recordPacking")) {
			addToURLBuffer("&recordPacking=");
			addToURLBuffer(super.getProperties().getExtraProperty("recordPacking"));
		}

		if (getURLBuffer().indexOf("sortKeys=") < 0 && null != super.getProperties().getExtraProperty("sortKeys")) {
			addToURLBuffer("&sortKeys=");
			addToURLBuffer(super.getProperties().getExtraProperty("sortKeys"));
		}

		if (getURLBuffer().indexOf("recordXPath=") < 0 && null != super.getProperties().getExtraProperty("recordXPath")) {
			addToURLBuffer("&recordXPath=");
			addToURLBuffer(super.getProperties().getExtraProperty("recordXPath"));
		}

		if (getURLBuffer().indexOf("resultSetTTL=") < 0 && null != super.getProperties().getExtraProperty("resultSetTTL")) {
			addToURLBuffer("&resultSetTTL=");
			addToURLBuffer(super.getProperties().getExtraProperty("resultSetTTL"));
		}

	}

	/**
	 * See the SearchAdapter abstract method doPerform
	 * 
	 * @exception Throwable
	 */
	public ArrayList doPerform() throws Throwable {
		SRWContentHandler eCHandler = new SRWContentHandler();
		eCHandler.setSearchAdapterProperties(super.getProperties());
		eCHandler.setSearchCriteria(super.getSearchCriteria());
		DiskCacheEntry entry = DeusExMachina._DiskCache().getEntry(super.getAugmentedSearchURL(), "UTF8");

		if (null != entry) {
			Reader reader = entry.getReader("UTF8");

			if (null != reader) {
				eCHandler = (SRWContentHandler) ResultSetUnifier.processXML(reader, eCHandler, "UTF-8");
			}
		}

		ArrayList batch = eCHandler.getResults();
		super.setTheoreticalAvailableResults(eCHandler.getFound());
		super.setDiagnosticCode(eCHandler.getDiagnosticCode());
		return batch;
	}

	/**
	 * See the SearchAdapter abstract method doNextBatch
	 * 
	 * @exception Throwable
	 */
	public boolean doNextBatch() throws Throwable {
		return false;
	}

	/**
	 * See the SearchAdapter abstract method doStopNice
	 * 
	 * @exception Throwable
	 */
	public void doStopNice() throws Throwable {
		// does nothing here
	}

	/**
	 * See the SearchAdapter abstract method doStopForce
	 * 
	 * @exception Throwable
	 */
	public void doStopForce() throws Throwable {
		// does nothing here
	}

	/** Class display string */
	public String toString() {
		return "o.m.d.a.SRUSearchAdapterImpl";
	}
} // -- EOF
